package ucanuup.cc.httpclient;


import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;

import ucanuup.cc.string.JsonUtil;

/**
 * 文件名： com.bozhon.util.WsUtil.java
 * 作者： WenBin
 * 日期： 2017年3月24日
 * 功能说明：
 * =========================================================
 * 修改记录：
 * 修改作者 日期 修改内容
 * =========================================================
 * Copyright (c) 2010-2011 .All rights reserved.
 */
public class HttpClientUtil {

	// private static final Logger log = LoggerFactory.getLogger(WsUtil.class);
	/** 私有化构造方法 */
	private HttpClientUtil() {
		super();
	}
	// http 请求常量
	/** httpclient socket 超时 */
	public static final int			HTTPCLIENT_SOCKET_TIME_OUT	= 30000;

	/** httpclient 连接超时 */
	public static final int			HTTPCLIENT_CONNECT_TIME_OUT	= 30000;

	/** 最基础的路径 */
	private static final String RECEPTION_PATH = "";

	/** 最基础的路径 */
	private static final String BATH_PATH = "";

	/**
	 * @Method: com.bozhon.webservice.util.WsUtil.getJsonObject
	 * @Description: 通过WebService路径获取 JSON的 String 内容
	 * @author: WenBin
	 * @date: 2017年3月24日
	 * @version: 1.0
	 * @param relativePath
	 *            相对路径
	 * @return
	 * 		String JSON格式的字符串
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	@Deprecated
	public static String doGetJsonRelativePath(String relativePath) {

		/*
		 * log.info("[请求的路径]:{}",BATH_PATH+relativePath);
		 * WebClient client = WebClientBeanFactory.getInstance(BATH_PATH+relativePath);
		 * String str = client.type(MediaType.TEXT_HTML).accept(MediaType.TEXT_HTML).get(String.class);
		 * log.info("[返回的json内容]:{}",str);
		 * return str;
		 */return null;
	}
	
	public static String doGetJsonBasePath(String path,Map<String,Object> params)throws ClientProtocolException, IOException{
		//String json = JSON.toJSONString(obj);
		
		if(params!=null && !params.isEmpty()) {
			List<NameValuePair> pairs = new ArrayList<NameValuePair>(params.size());
			for (String key :params.keySet()){
				pairs.add(new BasicNameValuePair(key, params.get(key).toString()));
			}
			path +="?"+EntityUtils.toString(new UrlEncodedFormEntity(pairs), "UTF-8");

		}
		
		String url = path;
		HttpGet httpPost = new HttpGet(url);
		// CloseableHttpClient client = HttpClients.createDefault();
		CloseableHttpClient client = HttpClientBuilder.create()
				.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)).build();
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(HTTPCLIENT_SOCKET_TIME_OUT)
				.setConnectTimeout(HTTPCLIENT_CONNECT_TIME_OUT).build();// 设置请求和传输超时时间
		httpPost.setConfig(requestConfig);
//		StringEntity entity = new StringEntity(json, "utf-8");// 解决中文乱码问题
//		entity.setContentEncoding("UTF-8");
//		entity.setContentType("application/json");
//		httpPost.setEntity(entity);
		HttpResponse resp = client.execute(httpPost);
		if (resp.getStatusLine().getStatusCode() == 200) {
			HttpEntity he = resp.getEntity();
			String respStr = EntityUtils.toString(he, "UTF-8");
			System.out.println(respStr);
			return respStr;
		}else{
			HttpEntity he = resp.getEntity();
			String respStr = EntityUtils.toString(he, "UTF-8");
			System.err.println("Error:"+respStr);
		}
		return null;
	}

	/**
	 * @Method: com.bozhon.webservice.util.WsUtil.doGetJsonAbsolutePath
	 * @Description: 通过WebService路径获取 JSON的 String对象
	 * @author: WenBin
	 * @date: 2017年3月24日
	 * @version: 1.0
	 * @param absolutePath
	 *            绝对路径
	 * @return
	 * 		String JSON格式的字符串
	 * @throws IOException
	 * @throws ClientProtocolException
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	public static String doGetJsonAbsolutePath(String absolutePath) throws ClientProtocolException, IOException {
		
		return doGetJsonBasePath(absolutePath,null);
		/*String json = "";
		String url = absolutePath;
		HttpGet httpPost = new HttpGet(url);
		// CloseableHttpClient client = HttpClients.createDefault();
		CloseableHttpClient client = HttpClientBuilder.create()
				.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)).build();
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(HTTPCLIENT_SOCKET_TIME_OUT)
				.setConnectTimeout(HTTPCLIENT_CONNECT_TIME_OUT).build();// 设置请求和传输超时时间
		httpPost.setConfig(requestConfig);
		StringEntity entity = new StringEntity(json, "utf-8");// 解决中文乱码问题
		entity.setContentEncoding("UTF-8");
		entity.setContentType("application/json");
		HttpResponse resp = client.execute(httpPost);
		if (resp.getStatusLine().getStatusCode() == 200) {
			HttpEntity he = resp.getEntity();
			String respStr = EntityUtils.toString(he, "UTF-8");
			System.out.println(respStr);
			return respStr;
		}else{
			HttpEntity he = resp.getEntity();
			String respStr = EntityUtils.toString(he, "UTF-8");
			System.err.println("Error:"+respStr);
		}
		return null;*/
	}
	
	public static String doGetJsonAbsolutePathWithToken(String absolutePath,String token) throws ClientProtocolException, IOException {
		String json = "";
		String url = absolutePath;
		HttpGet httpPost = new HttpGet(url);
		httpPost.setHeader("Authorization",""+token);
		// CloseableHttpClient client = HttpClients.createDefault();
		CloseableHttpClient client = HttpClientBuilder.create()
				.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)).build();
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(HTTPCLIENT_SOCKET_TIME_OUT)
				.setConnectTimeout(HTTPCLIENT_CONNECT_TIME_OUT).build();// 设置请求和传输超时时间
		httpPost.setConfig(requestConfig);
		StringEntity entity = new StringEntity(json, "utf-8");// 解决中文乱码问题
		entity.setContentEncoding("UTF-8");
		entity.setContentType("application/x-www-form-urlencoded");
		HttpResponse resp = client.execute(httpPost);
		if (resp.getStatusLine().getStatusCode() == 200) {
			HttpEntity he = resp.getEntity();
			String respStr = EntityUtils.toString(he, "UTF-8");
			System.out.println(respStr);
			return respStr;
		}else{
			HttpEntity he = resp.getEntity();
			String respStr = EntityUtils.toString(he, "UTF-8");
			System.err.println("Error:"+respStr);
		}
		return null;
	}
	
	
	

	/**
	 * @Method: com.bozhon.webservice.util.WsUtil.doGetJsonObjectRelativePath
	 * @Description: 通过 WebService相对路径获取 Object 对象
	 * @author: WenBin
	 * @date: 2017年3月24日
	 * @version: 1.0
	 * @param relativePath
	 *            相对路径
	 * @param clazz
	 *            需要返回的对象类型
	 * @return
	 * 		T 返回所需要的对象类型
	 * @throws IOException 
	 * @throws JsonMappingException 
	 * @throws JsonParseException 
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	@Deprecated
	public static <T> T doGetJsonObjectRelativePath(String relativePath, Class<T> clazz) throws JsonParseException, JsonMappingException, IOException {

		String json = HttpClientUtil.doGetJsonRelativePath(relativePath);
		T obj = JsonUtil.parseObject(json, clazz);
		return obj;
	}

	/**
	 * @Method: com.bozhon.webservice.util.WsUtil.doGetJsonObjectAbsolutePath
	 * @Description: 通过 WebService绝对路径获取 Object 对象
	 * @author: WenBin
	 * @date: 2017年3月24日
	 * @version: 1.0
	 * @param absolutePath
	 *            绝对路径
	 * @param clazz
	 *            需要返回的对象类型
	 * @return
	 * 		T 返回所需要的对象类型
	 * @throws IOException
	 * @throws ClientProtocolException
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	public static <T> T doGetJsonObjectAbsolutePath(String absolutePath, Class<T> clazz) throws ClientProtocolException, IOException {

		String json = HttpClientUtil.doGetJsonAbsolutePath(absolutePath);
		T obj = JsonUtil.parseObject(json, clazz);
		return obj;
	}

	/**
	 * @Method: com.bozhon.webservice.util.WsUtil.doPostJsonRelativePath
	 * @Description: 通过相对路径 请求无传参Post 请求 返回JSON字符串
	 * @author: WenBin
	 * @date: 2017年3月25日
	 * @version: 1.0
	 * @param relativePath
	 *            相对路径
	 * @return
	 * 		String JSON字符串
	 * @throws IOException
	 * @throws ClientProtocolException
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	@Deprecated
	public static String doPostJsonRelativePath(String relativePath) throws ClientProtocolException, IOException {

		String url = "http://192.168.15.31:8080/mmp/rest/query1";
		// POST的URL
		String ent = "{\"requestId\":\"assdfgasdf\",\"taskName\":\"assdfgasdf\",\"requestTime\":\"2017-3-22 08:00:00 000\",\"data\":{\"userId\":\"0001\"}}";
		HttpPost httpPost = new HttpPost(url);
		CloseableHttpClient client = HttpClients.createDefault();
		String respContent = null;

		// json方式
		StringEntity entity = new StringEntity(ent, "utf-8");// 解决中文乱码问题
		entity.setContentEncoding("UTF-8");
		entity.setContentType("application/json");
		httpPost.setEntity(entity);
		System.out.println();

		// 表单方式
		// List<BasicNameValuePair> pairList = new ArrayList<BasicNameValuePair>();
		// pairList.add(new BasicNameValuePair("name", "admin"));
		// pairList.add(new BasicNameValuePair("pass", "123456"));
		// httpPost.setEntity(new UrlEncodedFormEntity(pairList, "utf-8"));

		HttpResponse resp = client.execute(httpPost);
		if (resp.getStatusLine().getStatusCode() == 200) {
			HttpEntity he = resp.getEntity();
			respContent = EntityUtils.toString(he, "UTF-8");
			System.out.println(respContent);
		}
		return null;
	}

	/**
	 * @Method: com.bozhon.webservice.util.WsUtil.doPostJsonAbsolutePath
	 * @Description: 通过绝对路径 请求无传参Post 请求 返回JSON字符串
	 * @author: WenBin
	 * @date: 2017年3月25日
	 * @version: 1.0
	 * @param absolutePath
	 *            绝对路径
	 * @return
	 * 		String JSON的字符串
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	@Deprecated
	public static String doPostJsonAbsolutePath(String absolutePath) {

		/*
		 * log.info("[请求的路径]:{}",absolutePath);
		 * WebClient client = WebClientBeanFactory.getInstance(absolutePath);
		 * String str = client.type(MediaType.APPLICATION_JSON).accept(MediaType.TEXT_HTML).post("{}", String.class);
		 * log.info("[返回的json内容]:{}",str);
		 * return str;
		 */
		return null;
	}

	/**
	 * @Method: com.bozhon.webservice.util.WsUtil.doPostJsonRelativePath
	 * @Description: 通过相对路径 请求有传参Post 请求 返回JSON字符串(接待)
	 * @author: WenBin
	 * @date: 2017年3月25日
	 * @version: 1.0
	 * @param relativePath
	 *            相对路径
	 * @param jsonObj
	 *            传入java对象
	 * @return
	 * 		String 返回JSON字符串
	 * @throws IOException
	 * @throws ClientProtocolException
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	public static String doPostJsonRelativePath(String relativePath, Object jsonObj)
			throws ClientProtocolException, IOException {

		String stringEntity = JsonUtil.toJSONString(jsonObj);
		return doPostJsonRelativePath(relativePath, stringEntity);
	}

	/**
	 * @Method: com.bozhon.webservice.util.WsUtil.doPostJsonBasePath
	 * @Description: 通过相对路径 请求有传参Post 请求 返回JSON字符串(门卫)
	 * @author: Alan
	 * @date: 2017年8月21日
	 * @version: 1.0
	 * @param relativePath
	 *            相对路径
	 * @param jsonObj
	 *            传入java对象
	 * @return
	 * 		String 返回JSON字符串
	 * @throws IOException
	 * @throws ClientProtocolException
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	public static String doPostJsonBasePath(String relativePath, Object jsonObj)
			throws ClientProtocolException, IOException {

		String stringEntity = JsonUtil.toJSONString(jsonObj);
		return doPostJsonBasePath(relativePath, stringEntity);
	}

	/**
	 * @Method: com.bozhon.webservice.util.WsUtil.doPostJsonAbsolutePath
	 * @Description: 通过绝对路径 请求有传参Post 请求 返回JSON字符串
	 * @author: WenBin
	 * @date: 2017年3月25日
	 * @version: 1.0
	 * @param absolutePath
	 *            绝对路径
	 * @param jsonObj
	 *            传参的java对象
	 * @return
	 * 		String JSON 字符串
	 * @throws IOException
	 * @throws ClientProtocolException
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	public static String doPostJsonAbsolutePath(String absolutePath, Object jsonObj)
			throws ClientProtocolException, IOException {

		String stringEntity = JsonUtil.toJSONString(jsonObj);
		System.out.println("httpclient请求对象："+stringEntity);
		System.out.println("httpclient请求路径："+absolutePath);
		return doPostJsonAbsolutePath(absolutePath, stringEntity);
	}

	/**
	 * @Method: com.bozhon.webservice.util.WsUtil.doPostJsonAbsolutePath
	 * @Description: 通过json 请求并返回 json字符串
	 * @author: WenBin
	 * @date: 2017年3月25日
	 * @version: 1.0
	 * @param absolutePath
	 *            绝对路径
	 * @param json
	 *            传入的JSON字符串
	 * @return
	 * 		String JSON字符串
	 * @throws IOException
	 * @throws ClientProtocolException
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	public static String doPostJsonAbsolutePath(String absolutePath, String json)
			throws ClientProtocolException, IOException {

		String url = absolutePath;
		HttpPost httpPost = new HttpPost(url);
		// CloseableHttpClient client = HttpClients.createDefault();
		CloseableHttpClient client = HttpClientBuilder.create()
				.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)).build();
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(HTTPCLIENT_SOCKET_TIME_OUT)
				.setConnectTimeout(HTTPCLIENT_CONNECT_TIME_OUT).build();// 设置请求和传输超时时间
		httpPost.setConfig(requestConfig);
		StringEntity entity = new StringEntity(json, "utf-8");// 解决中文乱码问题
		entity.setContentEncoding("UTF-8");
		entity.setContentType("application/json");
		httpPost.setEntity(entity);
		HttpResponse resp = client.execute(httpPost);
		if (resp.getStatusLine().getStatusCode() == 200) {
			HttpEntity he = resp.getEntity();
			String respStr = EntityUtils.toString(he, "UTF-8");
			System.out.println(respStr);
			return respStr;
		}else{
			HttpEntity he = resp.getEntity();
			String respStr = EntityUtils.toString(he, "UTF-8");
			System.err.println("Error:"+respStr);
		}
		return null;
	}

	/**
	 * @Method: com.bozhon.webservice.util.WsUtil.doPostJsonRelativePath
	 * @Description: 通过json 请求并返回 json字符串(接待)
	 * @author: WenBin
	 * @date: 2017年3月25日
	 * @version: 1.0
	 * @param relativePath
	 *            相对路径
	 * @param json
	 *            传入的json
	 * @return
	 * 		String 返回的json字符串
	 * @throws IOException
	 * @throws ClientProtocolException
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	public static String doPostJsonRelativePath(String relativePath, String json)
			throws ClientProtocolException, IOException {

		String url = RECEPTION_PATH + relativePath;
		System.out.println("url="+url);
		return HttpClientUtil.doPostJsonAbsolutePath(url, json);
	}

	/**
	 * @Method: com.bozhon.webservice.util.WsUtil.doPostJsonBasePath
	 * @Description: 通过json 请求并返回 json字符串(门卫)
	 * @author: WenBin
	 * @date: 2017年3月25日
	 * @version: 1.0
	 * @param relativePath
	 *            相对路径
	 * @param json
	 *            传入的json
	 * @return
	 * 		String 返回的json字符串
	 * @throws IOException
	 * @throws ClientProtocolException
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	public static String doPostJsonBasePath(String relativePath, String json)
			throws ClientProtocolException, IOException {

		String url = BATH_PATH + relativePath;
		return HttpClientUtil.doPostJsonAbsolutePath(url, json);
	}

	/**
	 * @Method: com.bozhon.webservice.util.WsUtil.doPostJsonObjectAbsolutePath
	 * @Description: 通过绝对路径 请求有传参Post 请求 返回对象
	 * @author: WenBin
	 * @date: 2017年3月25日
	 * @version: 1.0
	 * @param absolutePath
	 * @param clazz
	 * @return
	 * 		T
	 * @throws IOException
	 * @throws ClientProtocolException
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	public static <T> T doPostJsonObjectAbsolutePath(String absolutePath, Class<T> clazz, Object jsonObj)
			throws ClientProtocolException, IOException {

		String json = HttpClientUtil.doPostJsonAbsolutePath(absolutePath, jsonObj);
		T obj = JsonUtil.parseObject(json, clazz);
		return obj;
	}

	/**
	 * @Method: com.bozhon.webservice.util.WsUtil.doPostJsonObjectRelativePath
	 * @Description: 通过相对路径 请求有传参Post 请求 返回对象(接待)
	 * @author: WenBin
	 * @date: 2017年3月25日
	 * @version: 1.0
	 * @param relativePath
	 * @param clazz
	 * @return
	 * 		T
	 * @throws IOException
	 * @throws ClientProtocolException
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	public static <T> T doPostJsonObjectRelativePath(String relativePath, Class<T> clazz, Object jsonObj)
			throws ClientProtocolException, IOException {

		String json = HttpClientUtil.doPostJsonRelativePath(relativePath, jsonObj);
		T obj = JsonUtil.parseObject(json, clazz);
		return obj;
	}

	/**
	 * @Method: com.bozhon.webservice.util.WsUtil.doPostJsonObjectBasePath
	 * @Description: 通过相对路径 请求有传参Post 请求 返回对象(门卫)
	 * @author: WenBin
	 * @date: 2017年3月25日
	 * @version: 1.0
	 * @param relativePath
	 * @param clazz
	 * @return
	 * 		T
	 * @throws IOException
	 * @throws ClientProtocolException
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	public static <T> T doPostJsonObjectBasePath(String relativePath, Class<T> clazz, Object jsonObj)
			throws ClientProtocolException, IOException {

		String json = HttpClientUtil.doPostJsonBasePath(relativePath, jsonObj);
		T obj = JsonUtil.parseObject(json, clazz);
		return obj;
	}
}
